﻿using System;
using System.Collections.Generic;

namespace Ipmce.RemoteVoting.Common.Tools.Wcf.Unity.LifetimeManagers
{
	public class InstancesManager
	{
		/// <summary>
		/// Backing store for relating keys to object instances for Unity.
		/// </summary>
		protected readonly Dictionary<Guid, object> _instances = new Dictionary<Guid, object>();

		/// <summary>
		/// Registers the given instance with the given key into the backing store.
		/// </summary>
		/// <param name="key">Key to associate with the object instance.</param>
		/// <param name="value">Object instance to associate with the given key in the backing store.</param>
		public void RegisterInstance(Guid key, object value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}

			_instances.Add(key, value);
		}

		/// <summary>
		/// Finds the object associated with the given key.
		/// </summary>
		/// <param name="key">Key used to find the associated object instance.</param>
		/// <returns>The object instance associated with the supplied key.  If no instance is registered, null is returned.</returns>
		public object FindInstance(Guid key)
		{
			object obj = null;

			// We don't care whether or not this succeeds or fails.
			_instances.TryGetValue(key, out obj);
			return obj;
		}

		/// <summary>
		/// Removes the given key from the backing store.  This method will also dispose of the associated object instance if it implements <see cref="System.IDisposable"/>.
		/// </summary>
		/// <param name="key">Key to remove from the backing store.</param>
		public void RemoveInstance(Guid key)
		{
			// We don't want to use FindInstance JUST IN CASE somehow a key gets in there with a null object.
			object instance = null;

			if (_instances.ContainsKey(key))
			{
				// Get the instance.
				instance = _instances[key];

				// See if it needs disposing.
				var disposable = instance as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}

				// Remove it from the instances list.
				_instances.Remove(key);
			}
		}
	}
}